﻿using System;
using System.Text;
using System.Web;

namespace Net.Formats.oEmbed
{
    /// <summary>
    /// Requests sent to the API endpoint must be HTTP GET requests, 
    /// with all arguments sent as query parameters. All arguments must be urlencoded 
    /// (as per RFC 1738).
    /// The following query parameters are defined as part of the spec.
    /// </summary>
    public class RequestParameters
    {
        Uri providerEndpoint;
        Uri resourceUrl;
        int? maxWidth;
        int? maxHeight;
        ResponseFormat? format;

        /// <summary>
        /// The provider API endpoint.
        /// It must point to an HTTP endpoint URL (not HTTPS) which implements the oEmbed API.
        /// </summary>
        public Uri ProviderEndpoint
        {
            get { return providerEndpoint; }
            set
            {
                if ( providerEndpoint != value )
                    providerEndpoint = value;
            }
        }

        /// <summary>
        /// The URL to retrieve embedding information for. Required.
        /// If <see cref="Net.Formats.oEmbed.RequestParameters.ProviderEndpoint">ProviderEndpoint</see>
        /// property value is not defined, will try and use discovery to find out provider endpoint url.
        /// </summary>
        public Uri ResourceUrl
        {
            get
            {
                if ( resourceUrl == null )
                    throw new ArgumentNullException( "ResourceUrl", "Resource url is a required parameter." );
                return resourceUrl;
            }
            set
            {
                if ( resourceUrl != value )
                    resourceUrl = value;
            }
                
        }

        /// <summary>
        /// The maximum width of the embedded resource. 
        /// Only applies to some resource types. 
        /// For supported resource types, this parameter must be respected by providers.
        /// </summary>
        public int? MaxWidth
        {
            get { return maxWidth; }
            set
            {
                if ( maxWidth != value )
                    maxWidth = value;
            }
        }

        /// <summary>
        /// The maximum height of the embedded resource. 
        /// Only applies to some resource types. 
        /// For supported resource types, this parameter must be respected by providers.
        /// </summary>
        public int? MaxHeight
        {
            get { return maxHeight; }
            set
            {
                if ( maxHeight != value )
                    maxHeight = value;
            }
        }

        /// <summary>
        /// The required response format. 
        /// When not specified, the provider can return any valid response format. 
        /// When specified, the provider must return data in the request format, 
        /// else return an error.
        /// </summary>
        public ResponseFormat? Format
        {
            get { return format; }
            set
            {
                if ( format != value )
                    format = value;
            }
        }

        /// <summary>
        /// Create request url, using available request parameters
        /// </summary>
        /// <returns>Request url</returns>
        public Uri GenerateUrl( )
        {
            var urlBulder = new StringBuilder( );
            urlBulder.AppendFormat( "{0}?", providerEndpoint.AbsoluteUri );
            urlBulder.AppendFormat( "url={0}", HttpUtility.UrlEncode( resourceUrl.AbsoluteUri ) );

            if ( maxWidth.HasValue )
                urlBulder.AppendFormat( "&maxwidth={0}", maxWidth.Value );

            if ( maxHeight.HasValue )
                urlBulder.AppendFormat( "&maxheight={0}", maxHeight.Value );

            if ( format.HasValue )
                urlBulder.AppendFormat( "&format={0}", format.Value.ToString( ).ToLower() );

            return new Uri( urlBulder.ToString( ) );
        }
    }
}